﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace Bitcoin.IO
{
    public static class BinaryReaderExtension
    {
        public static Transaction ReadTransaction(this BinaryReader reader)
        {
            var version = reader.ReadUInt32();

            var inputCount = reader.ReadVarIntEncoded();
            var inputs = new List<TransactionInput>();
            for (var inputIndex = 0UL; inputIndex < inputCount; inputIndex++)
            {
                var input = reader.ReadTransactionInput();
                inputs.Add(input);
            }

            var outputCount = reader.ReadVarIntEncoded();
            var outputs = new List<TransactionOutput>();
            for (var outputIndex = 0UL; outputIndex < outputCount; outputIndex++)
            {
                var output = reader.ReadTransactionOutput();
                outputs.Add(output);
            }

            var lockTime = reader.ReadUInt32();

            var transaction = new Transaction(version, inputs, outputs, lockTime);
            return transaction;
        }

        public static TransactionInput ReadTransactionInput(this BinaryReader reader)
        {
            var outpointHash = reader.ReadBytes(32);
            var outpointIndex = reader.ReadUInt32();
            var scriptLength = reader.ReadVarIntEncoded();
            var scriptBytes = reader.ReadBytes((int)scriptLength);
            var sequence = reader.ReadUInt32();

            var input = new TransactionInput(outpointHash, outpointIndex, scriptBytes, sequence);
            return input;
        }

        public static TransactionOutput ReadTransactionOutput(this BinaryReader reader)
        {
            var value = reader.ReadUInt64();
            var scriptLength = reader.ReadVarIntEncoded();
            var scriptBytes = reader.ReadBytes((int)scriptLength);

            var output = new TransactionOutput(value, scriptBytes);
            return output;
        }


        public static UInt64 ReadVarIntEncoded(this BinaryReader reader)
        {
            UInt64 value;
            var key = reader.ReadByte();
            if (key == 0xff)
            {
                value = reader.ReadUInt64();
            }
            else if (key == 0xfe)
            {
                value = reader.ReadUInt32();
            }
            else if (key == 0xfd)
            {
                value = reader.ReadUInt16();
            }
            else
            {
                value = key;
            }
            return value;
        }

    }
}
